<head><meta name="viewport" content="user-scalable=no,initial-scale=1,maximum-scale=1">
<meta charset=utf-8>
<style>
body { margin: 0px; }
canvas { width:100%; height:100%; overflow: hidden; }
</style>
<script type="text/javascript" src="../h3du_min.js"></script>
<script type="text/javascript" src="implicit.js"></script>
<script type="text/javascript" src="../extras/camera.js"></script>
<script type="text/javascript" src="../extras/frame.js"></script>
<script type="text/javascript" src="demoutil.js"></script>
<script type="text/javascript" src="../extras/meshjson.js"></script>
</head>
<body>
<div style="position:absolute;left:0;top:1em" id=links>
</div>
<div id="settings" style="position:absolute;left:0;top:3em"></div>
<canvas id=canvas></canvas>
<script id="demo">
/* global H3DU, ImplicitSurface, addLink, pushSettings */
// <!--
/*
 Any copyright to this file is released to the Public Domain.
 http://creativecommons.org/publicdomain/zero/1.0/
 If you like this, you should donate
 to Peter O. (original author of
 the Public Domain HTML 3D Library) at:
 http://peteroupc.github.io/
*/
  var allsettings = {};
  function Cylinder(radius) {
    "use strict";
    this.c = radius * radius;
    this.sample = function(x, y, z) {
      return x * x + z * z - this.c;
    };
  }

/* exported PlaneSurface */
  function PlaneSurface(a, b, c, d) {
    "use strict";
    this.a = a;
    this.b = b;
    this.c = c;
    this.d = d;
    this.sample = function(x, y, z) {
      return a * x + b * y + c * z + d;
    };
  }

  function Ellipsoid(a, b, c) {
    "use strict";
    this.a = a * a;
    this.b = b * b;
    this.c = c * c;
    this.sample = function(x, y, z) {
      return x * x / this.a + y * y / this.b + z * z / this.c - 1;
    };
  }

  function HyperboloidOneSheet(a, b, c) {
    "use strict";
    this.a = a * a;
    this.b = b * b;
    this.c = c * c;
    this.sample = function(x, y, z) {
      return x * x / this.a + z * z / this.c - y * y / this.b - 1;
    };
  }

  function makeImplicit(func) {
    "use strict";
    var surf = new ImplicitSurface(func);
    var mesh = new H3DU.Mesh();
    mesh.color3("blue");
    surf.evalSurface(mesh, 48, 48, 48, -5, 5, -5, 5, -5, 5);
    return mesh.toMeshBuffer();
  }

  var shapeGroup = new H3DU.ShapeGroup();

  var link1 = null;
  addLink("Ellipsoid", link1 = function() {
    "use strict";
    pushSettings(allsettings, shapeGroup, function(allsettings) {
      return makeImplicit(
    new Ellipsoid(
      allsettings["superel-x"],
      allsettings["superel-y"],
      allsettings["superel-z"]
    ));
    }, {
      "superel-x":["X radius", 1, 0.05, 2.0, 0.05],
      "superel-y":["Y radius", 1, 0.05, 2.0, 0.05],
      "superel-z":["Z radius", 1, 0.05, 2.0, 0.05]
    });
  });

  addLink("Hyperboloid of One Sheet", function() {
    "use strict";
    pushSettings(allsettings, shapeGroup, function(allsettings) {
      return makeImplicit(
    new HyperboloidOneSheet(
      allsettings["hyp1-x"],
      allsettings["hyp1-y"],
      allsettings["hyp1-z"]
    ));
    }, {
      "hyp1-x":["X radius", 1, 0.05, 2.0, 0.05],
      "hyp1-y":["Y radius", 1, 0.05, 2.0, 0.05],
      "hyp1-z":["Z radius", 1, 0.05, 2.0, 0.05]
    });
  });
  addLink("Cylinder", function() {
    "use strict";
    pushSettings(allsettings, shapeGroup, function(allsettings) {
      var cyl = new Cylinder(
      allsettings["cylinder-rad"]
   );
      return makeImplicit(cyl);
    }, {"cylinder-rad":["Radius", 1, 0.05, 2.0, 0.05]});
  });

  addLink("Union: Cylinder and sphere", function() {
    "use strict";
    pushSettings(allsettings, shapeGroup, function(allsettings) {
      var cyl = new Cylinder(
      allsettings["cylinder-rad"]
   );
      var erad = allsettings["sphere-rad"];
      var ell = new Ellipsoid(erad, erad, erad);
      return makeImplicit(
     ImplicitSurface.union(cyl, ell));
    }, {
      "cylinder-rad":["Cylinder radius", 1, 0.05, 2.0, 0.05],
      "sphere-rad":["Sphere radius", 1.3, 0.05, 2.0, 0.05]
    });
  });
  addLink("Intersection: Cylinder and sphere", function() {
    "use strict";
    pushSettings(allsettings, shapeGroup, function(allsettings) {
      var cyl = new Cylinder(
      allsettings["cylinder-rad"]
   );
      var erad = allsettings["sphere-rad"];
      var ell = new Ellipsoid(erad, erad, erad);
      return makeImplicit(
     ImplicitSurface.intersection(cyl, ell));
    }, {
      "cylinder-rad":["Cylinder radius", 1, 0.05, 2.0, 0.05],
      "sphere-rad":["Sphere radius", 1.3, 0.05, 2.0, 0.05]
    });
  });
  addLink("Cylinder minus sphere", function() {
    "use strict";
    pushSettings(allsettings, shapeGroup, function(allsettings) {
      var cyl = new Cylinder(
      allsettings["cylinder-rad"]
   );
      var erad = allsettings["sphere-rad"];
      var ell = new Ellipsoid(erad, erad, erad);
      return makeImplicit(
     ImplicitSurface.difference(cyl, ell));
    }, {
      "cylinder-rad":["Cylinder radius", 1, 0.05, 2.0, 0.05],
      "sphere-rad":["Sphere radius", 1.3, 0.05, 2.0, 0.05]
    });
  });
  addLink("Sphere minus cylinder", function() {
    "use strict";
    pushSettings(allsettings, shapeGroup, function(allsettings) {
      var cyl = new Cylinder(
      allsettings["cylinder-rad"]
   );
      var erad = allsettings["sphere-rad"];
      var ell = new Ellipsoid(erad, erad, erad);
      return makeImplicit(
     ImplicitSurface.difference(ell, cyl));
    }, {
      "cylinder-rad":["Cylinder radius", 1, 0.05, 2.0, 0.05],
      "sphere-rad":["Sphere radius", 1.3, 0.05, 2.0, 0.05]
    });
  });

  // Create the 3D scene; find the HTML canvas and pass it
  // to Scene3D.
  var scene = new H3DU.Scene3D(document.getElementById("canvas"));
  var input = new H3DU.InputTracker(scene.getCanvas());
  scene.setClearColor("white");
  var sub = new H3DU.Batch3D();
  var camera = new H3DU.Camera(sub, 45, 1, 100);
  camera.setDistance(5);
  var pc = new H3DU.FrameCounterDiv();
  link1();
  sub.addShape(shapeGroup);
  H3DU.renderLoop(function() {
    "use strict";
    pc.update();
    camera.update(input.update());
    sub.getLights().setDirectionalLight(0, camera.getPosition());
    scene.render(sub);
  });
// -->
</script>
</body>
